'use strict';

import { ModelStatus } from './types'

export enum UserType {
    SUPER_ADMIN = 'SUPER_ADMIN',
    ADMIN = 'ADMIN'
}


export default app => {
  const mongoose = app.mongoose;
  const Schema = mongoose.Schema;

  const userSchema = new Schema({
    /**
    * 用户名
    */
    name: { type: String, default: '', index: true },
    /**
     * 用户密码（经过MD5加密的数据）
     */
    pass: { type: String, default: '' },
    /**
     * 登录错次数
     */
    loginErrNum: { type: Number, default: 0 },
    /**
     * 创建时间
     */
    createTime: { type: Date, default: new Date() },
    /**
     * 用户类型
     */
    type: { type: String, enum: [ UserType.SUPER_ADMIN, UserType.ADMIN ], default: UserType.ADMIN },
    /**
     * 项目
     */
    projects: [{ type: Schema.Types.ObjectId, ref: 'Project' }],
    /**
     * 是否启用
     */
    enabled: { type: Boolean, default: true },
    /**
     * 状态，是否删除
     */
    status: { type: Number, enum: [ ModelStatus.NORMAL, ModelStatus.DELETE ], default: ModelStatus.NORMAL }
  });

  /**
   * 获取当前所有的管理员账号的个数
   */
  userSchema.statics.findSuperAdminCount = function() {
    return this.countDocuments({ type: UserType.SUPER_ADMIN, status: ModelStatus.NORMAL });
  };

  /**
   * 根据账号获取用户信息
   * isSuper: 是否是超级管理员
   */
  userSchema.statics.findWithUser = function(name, isSuper = false) {
    const query: any = { name, status: ModelStatus.NORMAL }
    if (isSuper) {
      query.type = UserType.SUPER_ADMIN
    }
    return this.findOne(query)
  };

  /**
   * 根据ID获取用户信息
   */
  userSchema.statics.findWithID = function(id) {
    return this.findOne({ 
      _id: mongoose.Types.ObjectId(id), 
      status: ModelStatus.NORMAL 
    })
  };

  /**
   * 更新当前用户数据
   */
  userSchema.statics.updateCurrentUser = function(name, upData) {
    return this.updateOne({ name, status: ModelStatus.NORMAL }, upData);
  };

  /**
   * 获取所有可使用的账号
   */
  userSchema.statics.findAllCount = function(other = {}) {
    return this.countDocuments({ status: ModelStatus.NORMAL, ...other });
  };

  /**
   * 获取列表数据
   */
  userSchema.statics.findList = function({ pageSize, pageNum }, other = {}) {
    const params = { status: ModelStatus.NORMAL, ...other };
    const skip = (pageNum - 1) * pageSize;
    const model = this
    .find(params, 'name createTime type projects enabled loginErrNum')
    .populate({
      path: 'projects',
      select: 'name status'
    })
    .skip(skip)
    .limit(pageSize);
    model.sort({ createTime: -1 });
    return model.exec();
  };

  /**
   * 添加登录错误次数
   */
  userSchema.methods.addLoginErrNum = function() {
    this.loginErrNum += 1;
    return this.model('User').updateOne(
      { name: this.name, status: ModelStatus.NORMAL },
      { loginErrNum: this.loginErrNum });
  };

  /**
   * 清除登录错误次数
   */
  userSchema.methods.clearLoginErrNum = function() {
    this.loginErrNum = 0;
    return this.model('User').updateOne(
      { name: this.name, status: ModelStatus.NORMAL },
      { loginErrNum: this.loginErrNum });
  };


  /**
   * 删除用户
   */
  userSchema.statics.removeUser = function(id) {
    return this.updateOne({
      _id: mongoose.Types.ObjectId(id),
    }, {
      status: ModelStatus.DELETE
    });
  };

  /**
   * 更新用户数据
   */
  userSchema.statics.updateUser = function(id, upData) {
    return this.updateOne({
      _id: mongoose.Types.ObjectId(id),
    }, upData);
  };

  /**
   * 添加项目
   */
  userSchema.statics.addProject = async function(id, projectId) {
    return this.updateOne({
      _id: mongoose.Types.ObjectId(id),
    }, {
      $push: {
        projects: mongoose.Types.ObjectId(projectId),
      },
    });
  };

  /**
   * 删除项目
   */
  userSchema.statics.removeProject = async function(id, projectId) {
    // 删除父节点里面的数据
    await this.updateOne({
      _id: mongoose.Types.ObjectId(id),
    }, {
      $pull: {
        projects: mongoose.Types.ObjectId(projectId),
      },
    });
  }

  /**
   * 获取当前账号下的项目列表
   */
  userSchema.statics.projectList = async function(id) {
    return this.findOne({ 
      _id: mongoose.Types.ObjectId(id), 
    }).populate({
      path: 'projects',
      select: 'name description createTime status createUser',
      populate:{
        path: 'createUser',
        select: 'name'
      }
    })
  };

  return mongoose.model('User', userSchema, 'users');
}
